package com.wf.smartcomm.server.yun;


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import com.google.gson.Gson;
import com.wf.smartcomm.server.apns.IApnsService;
import com.wf.smartcomm.server.apns.model.Payload;
import com.wf.smartcomm.server.bean.Call;
import com.wf.smartcomm.server.bean.User;
import com.wf.smartcomm.server.client.action.BaseAction;
import com.wf.smartcomm.server.model.CallAuthen;
import com.wf.smartcomm.server.model.CallEstablish;
import com.wf.smartcomm.server.model.CallHangup;
import com.wf.smartcomm.server.model.PushMessage;
import com.wf.smartcomm.server.push.Pusher;
import com.wf.smartcomm.server.service.CallService;
import com.wf.smartcomm.server.service.UserService;
import com.wf.smartcomm.server.util.ConstantUtils;
import com.wf.smartcomm.server.util.PushUtils;

import sun.awt.geom.AreaOp.CAGOp;

@Controller
@Scope("prototype")
public class CallbackAction extends BaseAction{
	@Resource
	private UserService userService;
	
	@Resource
	private CallService callService;
	
	private static final Logger log = Logger.getLogger(CallbackAction.class);
	
	public void callback() throws Exception{
		Document doc = null;
		String body = "";
		log.info(" =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= starts =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= ");
		try {
			// 解析流，打印log
			InputStream in = request.getInputStream();
			BufferedReader bf = new BufferedReader(new InputStreamReader(in));
			String str = null;
			StringBuffer xmlfile = new StringBuffer();
			while ((str = bf.readLine()) != null) {
				xmlfile.append(str);
			}
			log.info(" --- xml body --- :" + xmlfile);
			doc = DocumentHelper.parseText(xmlfile.toString());
		} catch (DocumentException e) {
			log.error(" *** DocumentException ***", e);
		} catch (IOException e1) {
			log.error(" *** IOException ***", e1);
		}
		Element root = doc.getRootElement();
		String action = root.elementTextTrim("action");
		if (action.equals("CallAuth")) {
			// 解析呼叫鉴权
			body = parseCallAuth(root);
		} else if (action.equals("CallEstablish")) {
			// 解析摘机请求
			body = parseCallEstablish(root);
		} else if (action.equals("Hangup")) {
			// 解析挂断请求
			body = parseHangup(root);
		}else if(action.equals("AccountLookup")){
			body = parseAccoutLookup(root);
		}
		// 设置返回header
		response.setHeader("Status-Code", "HTTP/1.1 200 OK");
		response.setHeader("Date", new Date() + "");
		response.setHeader("Content-Length", body.length() + "");
		try {
			// 输出 ，返回到客户端
			OutputStream opt = response.getOutputStream();
			OutputStreamWriter out = new OutputStreamWriter(opt);
			out.write(body);
			out.flush();
		} catch (IOException e) {
			log.error(" *** IOException ***", e);
		}
		log.info("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= end =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r\n");
	}
	
	private String parseAccoutLookup(Element root) {
		String username = root.elementTextTrim("id");
		log.info("token-------->"+username);	
		User user = userService.getUserByUsername(username);
		String result = "<?xml version='1.0' encoding='UTF-8' ?><Response><dname>user01</dname><voipid>"+user.getVoipAccount()+"</voipid><voippwd>"+user.getVoipPwd()+"</voippwd><hash>"+username+"</hash></Response>";
		log.info("result-------->"+result);
		return result;
	}

	private String parseCallAuth(Element e) throws Exception{
		log.info("--- parseCallAuth   start ---");
		CallAuthen call = new CallAuthen();
		call.setType(e.elementTextTrim("type"));
		call.setOrderId(e.elementTextTrim("orderid"));
		call.setSubId(e.elementTextTrim("subid"));
		call.setCaller(e.elementTextTrim("caller"));
		call.setCalled(e.elementTextTrim("called"));
		call.setCallSid(e.elementTextTrim("callSid"));
		log.info(" --- parseCallAuth --- :"+call.toString());
		Call callRecord = new Call();
		callRecord.setCallId(call.getCallSid());
		callRecord.setCaller(call.getCaller());
		callRecord.setCalled(call.getCalled());
		callRecord.setCreatedAt(new Date());
		callService.save(callRecord);
		/*User called = userService.getUserByVoip(call.getCalled());
		PushMessage msg = new PushMessage();
		msg.setPushType(ConstantUtils.PUSH_TYPE_CALLER_VOIP);
		msg.setData(call.getCaller());
		Pusher clientPusher = PushUtils.getClientPusher();
		IApnsService service = PushUtils.getApnsService();
		if (called.getDeviceType().equals(ConstantUtils.DEVICE_TYPE_ANDROID)) {
			clientPusher.push0x20Message(called.getPushId().getBytes(), new Gson().toJson(msg).getBytes());
		} else if(called.getDeviceType().equals(ConstantUtils.DEVICE_TYPE_APPLE)){
			Payload payload = new Payload();
			//payload.setAlert(ad.getSubject());
			payload.setBadge(0);
			//payload.setSound("default");
			payload.addParam("caller", call.getCaller());
			payload.addParam("type", ConstantUtils.PUSH_TYPE_CALLER_VOIP);
			service.sendNotification(called.getAppleToken(), payload);
		}
		clientPusher.close();*/
		
		//返回的数据,如果需要控制呼叫时长需要增加sessiontime
		String result = "<?xml version='1.0' encoding='UTF-8' ?><Response><statuscode>0000</statuscode><statusmsg>Success</statusmsg><record>1</record></Response>";
		
		return result;
	}
	
	private String parseCallEstablish(Element e) {
		log.info("--- parseCallEstablish   start   ");
		CallEstablish call = new CallEstablish();
		call.setType(e.elementTextTrim("type"));
		call.setOrderId(e.elementTextTrim("orderid"));
		call.setSubId(e.elementTextTrim("subid"));
		call.setCaller(e.elementTextTrim("caller"));
		call.setCalled(e.elementTextTrim("called"));
		call.setCallSid(e.elementTextTrim("callSid"));
		log.info(" --- CallEstablish --- : " + call.toString());
		//请在此处增加逻辑判断代码
		
		//返回的数据,如果需要控制呼叫时长需要增加sessiontime
		String result = "<?xml version='1.0' encoding='UTF-8' ?><Response><statuscode>0000</statuscode><statusmsg>Success</statusmsg><billdata>ok</billdata></Response>";
		log.info("--- parseCallEstablish   end ---");

		return result;
	}
	
	/**
	 * 解析挂断请求
	 * @param e Element
	 * @return result
	 */
	private String parseHangup(Element e) {
		log.info("---parseHangup   start---");
		// 封装 CallHangup
		CallHangup call = new CallHangup();
		call.setType(e.elementTextTrim("type"));
		call.setOrderId(e.elementTextTrim("orderid"));
		call.setSubId(e.elementTextTrim("subid"));
		call.setCaller(e.elementTextTrim("caller"));
		call.setCalled(e.elementTextTrim("called"));
		call.setByeType(e.elementTextTrim("byeType"));
		call.setStarttime(e.elementTextTrim("starttime"));
		call.setEndtime(e.elementTextTrim("endtime"));
		call.setBilldata(e.elementTextTrim("billdata"));
		call.setCallSid(e.elementTextTrim("callSid"));
		call.setRecordurl(e.elementTextTrim("recordurl"));
		log.info(" --- CallHangup --- : " + call.toString());
		//请在此处增加逻辑判断代码
		
		//返回的数据
		String result = "<?xml version='1.0' encoding='UTF-8'?><Response><statuscode>0000</statuscode><statusmsg>Success</statusmsg><totalfee>0.120000</totalfee></Response>";
		
		return result;
	}
}
